import mapboxgl from 'mapbox-gl';

// 基础事件类型
type BaseEvent = 
  | "load" | "error" | "render" | "idle" | "move" | "movestart" | "moveend" 
  | "zoom" | "zoomstart" | "zoomend" | "rotate" | "rotatestart" | "rotateend" 
  | "pitch" | "drag" | "dragstart" | "dragend" | "touchstart" | "touchmove" 
  | "touchend" | "mousedown" | "mouseup" | "mousemove" | "click" | "dblclick" 
  | "contextmenu" | "resize" | "webglcontextlost" | "webglcontextrestored";

// 图层事件类型
type LayerEvent = "mouseenter" | "mouseleave" | "click" | "mousemove" | "dblclick" | "contextmenu";

// 事件类型集合
type MapEvent = BaseEvent | LayerEvent;

// 事件回调函数类型
type EventCallback<T = any> = (event: T) => void;

// 事件注册配置
interface EventRegistration<T = any> {
  eventName: MapEvent;
  callback: EventCallback<T>;
  layerId?: string;
  once?: boolean;
  enabled?: boolean;
  options?: any;
}

// 内部存储的事件注册信息
interface InternalEventRegistration<T = any> extends EventRegistration<T> {
  handler: EventCallback<T>;
  remove: () => void;
}

// 事件管理器状态
interface EventManagerState {
  map: mapboxgl.Map | null;
  listeners: Map<string, Set<InternalEventRegistration>>;
  layerListeners: Map<string, Map<string, Set<InternalEventRegistration>>>;
  pendingEvents: EventRegistration[];
}

// 初始化状态
const state: EventManagerState = {
  map: null,
  listeners: new Map(),
  layerListeners: new Map(),
  pendingEvents: []
};

/**
 * 连接到地图实例
 */
export function connectMap(mapInstance: mapboxgl.Map): void {
  // 断开之前的连接
  if (state.map) {
    disconnectMap();
  }
  
  state.map = mapInstance;
  
  // 处理挂起的事件注册
  processPendingEvents();
  
  console.log('[MapEventManager] 已连接到地图实例');
}

/**
 * 断开与地图实例的连接
 */
export function disconnectMap(): void {
  if (!state.map) return;
  
  // 移除所有事件监听器
  removeAllListeners();
  
  // 重置状态
  state.map = null;
  state.pendingEvents = [];
  
  console.log('[MapEventManager] 已断开与地图实例的连接');
}

/**
 * 注册地图事件监听器
 */
export function onMapEvent<T = mapboxgl.MapboxEvent>(
  eventName: MapEvent, 
  callback: EventCallback<T>, 
  options?: {
    layerId?: string;
    once?: boolean;
    enabled?: boolean;
    priority?: number;
  }
): () => void {
  const config: EventRegistration<T> = {
    eventName,
    callback,
    layerId: options?.layerId,
    once: options?.once,
    enabled: options?.enabled ?? true
  };
  
  // 如果地图未连接，将事件加入待处理队列
  if (!state.map) {
    state.pendingEvents.push(config);
    console.log(`[MapEventManager] 地图未连接，事件 ${eventName} 已加入待处理队列`);
    
    // 返回注销函数
    return () => {
      const index = state.pendingEvents.findIndex(
        (e) => e.eventName === eventName && e.callback === callback && e.layerId === config.layerId
      );
      
      if (index !== -1) {
        state.pendingEvents.splice(index, 1);
        console.log(`[MapEventManager] 已从待处理队列移除事件 ${eventName}`);
      }
    };
  }
  
  // 注册事件
  return registerEvent(config);
}

/**
 * 一次性注册地图事件监听器
 */
export function onceMapEvent<T = mapboxgl.MapboxEvent>(
  eventName: MapEvent, 
  callback: EventCallback<T>, 
  options?: {
    layerId?: string;
    enabled?: boolean;
  }
): () => void {
  return onMapEvent(eventName, callback, {
    ...options,
    once: true
  });
}

/**
 * 移除地图事件监听器
 */
export function offMapEvent<T = mapboxgl.MapboxEvent>(
  eventName: MapEvent, 
  callback: EventCallback<T>, 
  layerId?: string
): void {
  const isLayerEvent = !!layerId;
  
  if (isLayerEvent) {
    removeLayerListener(eventName, callback, layerId);
  } else {
    removeBaseListener(eventName, callback);
  }
}

/**
 * 移除指定图层的所有事件监听器
 */
export function offLayerEvents(layerId: string): void {
  const layerMap = state.layerListeners.get(layerId);
  if (!layerMap) return;
  
  layerMap.forEach((listeners, eventName) => {
    listeners.forEach(registration => {
      registration.remove();
    });
  });
  
  state.layerListeners.delete(layerId);
  console.log(`[MapEventManager] 已移除图层 ${layerId} 的所有事件监听器`);
}

/**
 * 移除所有事件监听器
 */
export function offAllEvents(): void {
  removeAllListeners();
  state.pendingEvents = [];
  console.log('[MapEventManager] 已移除所有事件监听器');
}

/**
 * 启用事件监听器
 */
export function enableEvent(
  eventName: MapEvent, 
  callback: EventCallback, 
  layerId?: string
): boolean {
  return toggleEvent(eventName, callback, layerId, true);
}

/**
 * 禁用事件监听器
 */
export function disableEvent(
  eventName: MapEvent, 
  callback: EventCallback, 
  layerId?: string
): boolean {
  return toggleEvent(eventName, callback, layerId, false);
}

/**
 * 获取事件管理器状态
 */
export function getEventManagerState(): {
  connected: boolean;
  eventCount: number;
  layerEventCount: number;
  pendingEventCount: number;
} {
  return {
    connected: !!state.map,
    eventCount: Array.from(state.listeners.values()).reduce(
      (sum, listeners) => sum + listeners.size, 
      0
    ),
    layerEventCount: Array.from(state.layerListeners.values()).reduce(
      (sum, layerMap) => sum + Array.from(layerMap.values()).reduce(
        (layerSum, listeners) => layerSum + listeners.size, 
        0
      ),
      0
    ),
    pendingEventCount: state.pendingEvents.length
  };
}

/**
 * 内部：注册事件
 */
function registerEvent<T = mapboxgl.MapboxEvent>(
  config: EventRegistration<T>
): () => void {
  const { eventName, callback, layerId, once, enabled } = config;
  
  // 创建事件处理函数
  const handler: EventCallback<T> = (event) => {
    try {
      callback(event);
      
      // 如果是一次性事件，触发后自动移除
      if (once) {
        removeRegistration(registration); // 此时 registration 已声明
      }
    } catch (error) {
      console.error(`[MapEventManager] 事件处理出错 (${eventName}):`, error);
    }
  };

  const isLayerEvent = !!layerId;
  let remove: () => void;

  // **先声明 registration 变量，再赋值**
  let registration: InternalEventRegistration<T>;

  if (isLayerEvent && layerId) {
    // 图层事件注册
    state.map?.on(eventName as LayerEvent, layerId, handler);
    remove = () => state.map?.off(eventName as LayerEvent, layerId, handler);

    // 存储图层事件监听
    if (!state.layerListeners.has(layerId)) {
      state.layerListeners.set(layerId, new Map());
    }
    const eventListeners = state.layerListeners.get(layerId)!;
    if (!eventListeners.has(eventName)) {
      eventListeners.set(eventName, new Set());
    }

    // **此处才对 registration 赋值**
    registration = {
      ...config,
      handler,
      remove,
    };

    // **现在可以安全使用 registration**
    eventListeners.get(eventName)!.add(registration);
  } else {
    // 基础事件注册
    state.map?.on(eventName as BaseEvent, handler);
    remove = () => state.map?.off(eventName as BaseEvent, handler);

    if (!state.listeners.has(eventName)) {
      state.listeners.set(eventName, new Set());
    }

    // **此处才对 registration 赋值**
    registration = {
      ...config,
      handler,
      remove,
    };

    state.listeners.get(eventName)!.add(registration);
  }

  // 处理事件启用/禁用状态
  if (!enabled) {
    remove();
  }

  console.log(
    `[MapEventManager] 已${enabled ? '' : '禁用并'}注册事件 ${eventName}${
      layerId ? ` (图层: ${layerId})` : ''
    }`
  );

  // 返回注销函数
  return () => removeRegistration(registration);
}
/**
 * 内部：移除注册的事件
 */
function removeRegistration(registration: InternalEventRegistration): void {
  const { eventName, layerId, remove } = registration;
  
  // 调用移除函数
  remove();
  
  // 从存储中移除
  if (layerId) {
    const layerMap = state.layerListeners.get(layerId);
    if (layerMap) {
      const listeners = layerMap.get(eventName);
      if (listeners) {
        listeners.delete(registration);
        if (listeners.size === 0) {
          layerMap.delete(eventName);
          if (layerMap.size === 0) {
            state.layerListeners.delete(layerId);
          }
        }
      }
    }
  } else {
    const listeners = state.listeners.get(eventName);
    if (listeners) {
      listeners.delete(registration);
      if (listeners.size === 0) {
        state.listeners.delete(eventName);
      }
    }
  }
}

/**
 * 内部：移除基础事件监听器
 */
function removeBaseListener<T = mapboxgl.MapboxEvent>(
  eventName: MapEvent, 
  callback: EventCallback<T>
): void {
  const listeners = state.listeners.get(eventName);
  if (!listeners) return;
  
  const registration = Array.from(listeners).find(
    (reg) => reg.callback === callback
  );
  
  registration && removeRegistration(registration);
}

/**
 * 内部：移除图层事件监听器
 */
function removeLayerListener<T = mapboxgl.MapboxEvent>(
  eventName: MapEvent, 
  callback: EventCallback<T>, 
  layerId: string
): void {
  const layerMap = state.layerListeners.get(layerId);
  if (!layerMap) return;
  
  const listeners = layerMap.get(eventName);
  if (!listeners) return;
  
  const registration = Array.from(listeners).find(
    (reg) => reg.callback === callback
  );
  
  registration && removeRegistration(registration);
}

/**
 * 内部：移除所有事件监听器
 */
function removeAllListeners(): void {
  // 移除基础事件
  state.listeners.forEach((listeners, eventName) => {
    listeners.forEach(registration => {
      registration.remove();
    });
  });
  
  // 移除图层事件
  state.layerListeners.forEach((layerMap, layerId) => {
    layerMap.forEach((listeners, eventName) => {
      listeners.forEach(registration => {
        registration.remove();
      });
    });
  });
  
  // 清空存储
  state.listeners.clear();
  state.layerListeners.clear();
}

/**
 * 内部：处理挂起的事件
 */
function processPendingEvents(): void {
  if (!state.map) return;
  
  const pending = [...state.pendingEvents];
  state.pendingEvents = [];
  
  pending.forEach(config => {
    registerEvent(config);
  });
  
  console.log(`[MapEventManager] 已处理 ${pending.length} 个挂起的事件注册`);
}

/**
 * 内部：启用/禁用事件
 */
function toggleEvent(
  eventName: MapEvent, 
  callback: EventCallback, 
  layerId: string | undefined, 
  enable: boolean
): boolean {
  let registration: InternalEventRegistration | undefined;
  
  if (layerId) {
    const layerMap = state.layerListeners.get(layerId);
    if (layerMap) {
      const listeners = layerMap.get(eventName);
      if (listeners) {
        registration = Array.from(listeners).find(
          (reg) => reg.callback === callback
        );
      }
    }
  } else {
    const listeners = state.listeners.get(eventName);
    if (listeners) {
      registration = Array.from(listeners).find(
        (reg) => reg.callback === callback
      );
    }
  }
  
  if (registration) {
    if (enable) {
      // 重新注册事件
      registration.remove();
      state.map?.on(
        registration.eventName as any, 
        registration.layerId as any, 
        registration.handler
      );
      registration.remove = () => state.map?.off(
        registration.eventName as any, 
        registration.layerId as any, 
        registration.handler
      );
    } else {
      // 临时移除事件
      registration.remove();
      registration.remove = () => {}; // 防止重复移除
    }
    
    console.log(
      `[MapEventManager] 已${enable ? '启用' : '禁用'}事件 ${eventName}${
        registration.layerId ? ` (图层: ${registration.layerId})` : ''
      }`
    );
    
    return true;
  }
  
  return false;
}
